/*
 * @Author: swc shanwenchao12138@163.com
 * @Date: 2024-08-23 10:43:12
 * @LastEditors: swc
 * @LastEditTime: 2024-12-20 14:07:26
 * @FilePath: \xf\src\components\base\modal\o-approval-info\command.ts
 * @Description:
 * @Version: 2.0
 * @Autor: swc
 */
import { Tsrv, ifs, ts } from '@/services';
import { N_cFlowchart } from '@/types';

class T_cmd {
  // 主组件箱
  private compBox: ifs.I_compBox;

  // 主组件ID
  private compID: string;

  // 主组件实例
  private self: any;
  // 主组refs

  private graph: N_cFlowchart.x6Graph;

  // 内部联络单明细 节点数据
  private approvalNodes: Array<any>;

  public regGraphEvents: Map<
    N_cFlowchart.EVENTS,
    (e: N_cFlowchart.I_eventParams) => void
  > = new Map();

  // 主组件created里初始化
  public init(self: any, compBoxInfo: ifs.I_compBoxInfo) {
    this.self = self;
    this.compBox = compBoxInfo.TcompBox;
    this.compID = compBoxInfo.compID;

    // 注册节点 点击事件
    this.regGraphEvents.set(
      N_cFlowchart.EVENTS.NODE_CLICK,
      this.graphNodeClick
    );
  }

  graphNodeClick = (e: N_cFlowchart.I_eventParams) => {
    this.self.nodeClick(e.cell.id);
    // const node = e.node;
    // const nodeProp = node.getProp();
    // const data = nodeProp.data;
    // if (nodeProp.shape === 'bpmn-begin' || nodeProp.shape === 'bpmn-end') {
    //   this.self.nodeClick(data.id);
    // }
  };

  public setGraph(graph: N_cFlowchart.x6Graph) {
    this.graph = graph;
  }

  public setApprovalNodes(approvalNodes: Array<any>) {
    this.approvalNodes = approvalNodes;
  }

  /**
   * @description: 添加内部联络单日志
   * @param {string} id: 内部联络单id
   * @param {number} type: 0-收到消息 1-查看内容 2-批注 3-确认 4-驳回
   * @param {string} info: 备注
   * @return {*}
   * @author: swc
   * @Date: 2024-09-04 19:29:50
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  public addLiaisonLog(type: number, info: string) {
    return Tsrv.addLiaisonLog(this.self.liaisonID, type, info);
  }

  // 获取下一级审批人
  public getNextApprover(): Promise<any> {
    return new Promise((resolve, reject) => {
      const approvalNodes = this.approvalNodes;
      const curApprover = this.self.curApprover;
      // 根据规则————审批人只能有一个子集，所以直接取第一个
      const nextNodeInfo = curApprover.son_data[0];
      if (Tsrv.noValue(nextNodeInfo)) {
        resolve([true, []]);
        return;
      }
      const next = approvalNodes.find(
        item => item.f_code === nextNodeInfo.nodeCode
      );
      const nextNode = {
        id: next?.id,
        type: next.f_type,
        nodeID: next.f_code,
        confirm: next.confirm,
        order: next.sn,
        nodeData: next.graph_data ?? {},
        previousNodes: next.father_data ?? [],
        subsequentNodes: next.son_data ?? []
      };
      if (nextNode.type === 0) {
        // 审核人
        // resolve([false, { approver: [nextNode], approvalCondition: null }]);
        resolve([false, [nextNode]]);
      }
      if (nextNode.type === 1) {
        // const params = {
        //   liasionID: '540109426359541760',
        //   bpmnID: '540107610100080640'
        // };
        const conditionParams = {
          funName: this.self.approvalTableName,
          liasionID: this.self.liaisonID,
          graphID: this.self.graphData.id,
          id: nextNode.id,
          nodeID: nextNode.nodeID,
          previousNodes: nextNode.previousNodes,
          subsequentNodes: nextNode.subsequentNodes
        };
        this.getApproverByCond(
          nextNode?.nodeData?.condition?.value,
          conditionParams
          // params
        ).then(r => {
          const [b, p] = r;
          if (b) {
            // const _p = {
            //   id: '540458018249121794',
            //   nodeID: '227f8081-0d7f-445f-b595-d681835ec4b9'
            // };
            const nextApprovers = [];
            for (let i = 0; i < p.length; i++) {
              const n = approvalNodes.find(item => item.f_code === p[i].nodeID);
              if (!Tsrv.noValue(n)) {
                const _n = {
                  id: n?.id,
                  type: n.f_type,
                  nodeID: n.f_code,
                  confirm: n.confirm,
                  order: n.sn,
                  nodeData: n.graph_data ?? {},
                  previousNodes: n.father_data ?? [],
                  subsequentNodes: n.son_data ?? []
                };
                nextApprovers.push(_n);
              }
            }
            if (!Tsrv.noValue(nextApprovers)) {
              // resolve(n);
              // resolve([
              //   false,
              //   { approver: nextApprovers, approvalCondition: nextNode }
              // ]);
              resolve([false, [...nextApprovers, nextNode]]);
            }
          }
        });
      } else {
        reject(Tsrv.getI18nByValue('未能识别的节点类型'));
      }
    });
  }

  // 获取上一级审批人信息
  public getPrevApprover(baseNode: any, params: any = []): any {
    const approvalNodes = this.approvalNodes;
    const curApprover = baseNode;
    const prevNodesInfo = curApprover.previousNodes;
    if (prevNodesInfo.length === 0) {
      if (params.length === 0) {
        return [true, []];
      }
      return [false, params];
    }
    const prevNodes = [];
    for (let i = 0; i < prevNodesInfo.length; i++) {
      const ele = prevNodesInfo[i];
      const appointNode = approvalNodes.find(
        item => item.f_code === ele.nodeCode
      );
      if (!Tsrv.noValue(appointNode)) {
        // prevNodes.push(appointNode);
        prevNodes.push({
          id: appointNode?.id,
          type: appointNode.f_type,
          nodeID: appointNode.f_code,
          confirm: appointNode.confirm,
          order: appointNode.sn,
          nodeData: appointNode.graph_data ?? null,
          previousNodes: appointNode.father_data ?? [],
          subsequentNodes: appointNode.son_data ?? []
        });
      }
    }
    const prevNode = prevNodes.find(item => item.confirm === 1);
    if (prevNode.type === 0) {
      // 审核人
      params.push(prevNode);
      return [false, params];
    }
    if (prevNode.type === 1) {
      // 条件
      params.push(prevNode);
      return this.getPrevApprover(prevNode, params);
    }
    return [true, []];
  }

  // 获取审批人信息 通过条件
  public getApproverByCond(condition: string, params: any): Promise<any> {
    return new Promise((resolve, reject) => {
      if (!Tsrv.noValue(condition)) {
        Tsrv.doEvent(
          condition,
          Tsrv.getFunInfo(this.self.approvalTableName) as ifs.I_funInfo,
          () => params
        )
          .then(r => {
            if (r.isErr()) {
              this.self.$msg(r.errmsg);
              resolve(false);
            } else {
              const res = r.getReturnData('conf');
              const data = res.res.data.request;
              if (Tsrv.noValues(data, data?.nextApprovers)) {
                // if (Tsrv.noValues(data, data?.nextApprover)) {
                this.self.$msg(Tsrv.getI18nByValue('没有获取到下一级审批人'));
                return;
              }
              resolve([true, data.nextApprovers]);
              // resolve([true, data.nextApprover]);
            }
          })
          .catch(err => {
            console.error(err);
            reject(false);
          });
      }
    });
  }

  // 修改刚审核节点的审批状态 和 下一级的 序号
  public updateApprNodesStatus(
    nextNodes: Array<any>,
    status: number = 1
  ): Promise<boolean> {
    return new Promise((resolve, reject) => {
      // 条件节点、审批人节点的 审批状态和序号
      const approvers = nextNodes.filter(item => item.type === 0);
      const approvalCondition = nextNodes.filter(item => item.type === 1);
      const currentSn = this.self.curApprover.sn;
      const ctd = new ts.T_ctdArg();
      ctd
        .setTableName(Tsrv.globalVar.tableName.SYS_INTERNAL_LIAISON_SHEET_DET)
        .setDbType(Tsrv.globalVar.dbType.MYSQL);
      ctd.setRule({} as ifs.I_rule);
      const ctdUpdDatas: ifs.I_ctdUpdData[] = [];
      // 修改当前节点的审批状态
      const curUpdData = new ts.T_ctdUpdData();
      curUpdData.setDataRule({} as ifs.I_rule).setFileInfo({});
      const curData: ifs.I_fv[] = [];

      const curFilter = { id: this.self.curApprover.id };
      if (status) {
        curData.push(new ts.T_fv().setField('confirm').setValue(status));
      } else {
        curData.push(new ts.T_fv().setField('sn').setValue(0));
      }
      curUpdData.setFilter(curFilter);
      curUpdData.setRowData(...curData);
      ctdUpdDatas.push(curUpdData);
      // 当驳回时，同级的审批人节点，序号置为0
      const sameLevelNodes = this.approvalNodes.find(
        item => item.sn === currentSn
      );
      if (!status && !Tsrv.noValue(sameLevelNodes)) {
        const levelUpdData = new ts.T_ctdUpdData();
        levelUpdData.setDataRule({} as ifs.I_rule).setFileInfo({});
        const levelData: ifs.I_fv[] = [];

        const levelFilter = { id: sameLevelNodes.id };
        levelData.push(new ts.T_fv().setField('sn').setValue(0));
        levelUpdData.setFilter(levelFilter);
        levelUpdData.setRowData(...levelData);
        ctdUpdDatas.push(levelUpdData);
      }
      // 修改next节点的审批状态
      let filter: any = {};
      if (!Tsrv.noValue(nextNodes)) {
        nextNodes.forEach(ele => {
          const ctdUpdData = new ts.T_ctdUpdData();
          ctdUpdData.setDataRule({} as ifs.I_rule).setFileInfo({});
          const rowData: ifs.I_fv[] = [];

          filter = { id: ele.id };
          // rowData.push(new ts.T_fv().setField('confirm').setValue(status));
          if (approvalCondition.length > 0) {
            if (status) {
              ele.type === 0 &&
                rowData.push(
                  new ts.T_fv().setField('sn').setValue(currentSn + 2)
                );
              if (ele.type === 1) {
                rowData.push(
                  new ts.T_fv().setField('sn').setValue(currentSn + 1)
                );
                rowData.push(
                  new ts.T_fv().setField('confirm').setValue(status)
                );
              }
            } else {
              rowData.push(new ts.T_fv().setField('confirm').setValue(status));
              if (ele.type === 1) {
                rowData.push(new ts.T_fv().setField('sn').setValue(0));
              }
            }
          } else {
            if (status) {
              ele.type === 0 &&
                rowData.push(
                  new ts.T_fv().setField('sn').setValue(currentSn + 1)
                );
            } else {
              rowData.push(new ts.T_fv().setField('confirm').setValue(status));
            }
          }
          ctdUpdData.setFilter(filter);
          ctdUpdData.setRowData(...rowData);
          ctdUpdDatas.push(ctdUpdData);
        });
      }
      ctd.setUpdRecDataMany(...ctdUpdDatas);
      Tsrv.batRows(ctd).then(resp => {
        const [b, res, msg] = resp;
        msg && this.self.$msg(msg);
        if (b) {
          resolve(true);
        } else {
          reject();
        }
      });
    });
  }

  public updateLiaisonStatus(status: number): Promise<boolean> {
    return new Promise((resolve, reject) => {
      const dbType = Tsrv.globalVar.dbType.MYSQL;
      const tableName = Tsrv.globalVar.tableName.SYS_INTERNAL_LIAISON_SHEET;
      const rule = {} as ifs.I_rule;
      const upd = new ts.T_ctdUpdRec();
      const filter = {
        id: this.self.liaisonID
      };
      const updData = [new ts.T_fv().setField('f_status').setValue(status)]; // 更新数据
      upd.setData({}, filter, {} as ifs.I_rule, ...updData);
      Tsrv.updRows(tableName, dbType, rule, upd).then(([ok, res, err]) => {
        if (!ok || !err) {
          this.self.$msg(err ?? res.msg);
          resolve(false);
        } else {
          this.self.$msg(res.msg);
          resolve(true);
        }
      });
    });
  }

  /**
   * @description: 修改内部联络单状态 （0：审核中，1：已审核，9：已暂停，11：自作废）
   * @param {number} status
   * @return {*}
   * @author: swc
   * @Date: 2024-09-10 15:03:10
   * @LastEditors: zss
   * @LastEditTime: Do not edit
   */
  public liaisonAudit(status: number): Promise<boolean> {
    return new Promise((resolve, reject) => {
      const dbType = Tsrv.globalVar.dbType.MYSQL;
      const tableName = Tsrv.globalVar.tableName.SYS_INTERNAL_LIAISON_SHEET;
      const rule = {} as ifs.I_rule;
      const upd = new ts.T_ctdUpdRec();
      const filter = {
        id: this.self.liaisonID
      };
      const updData = [new ts.T_fv().setField('f_status').setValue(status)]; // 更新数据
      upd.setData({}, filter, {} as ifs.I_rule, ...updData);
      Tsrv.updRows(tableName, dbType, rule, upd)
        .then(([ok, res, err]) => {
          if (!ok || !err) {
            this.self.$msg(err ?? res.msg);
            resolve(false);
          } else {
            this.self.$msg(res.msg);
            resolve(true);
          }
        })
        .catch(er => {
          reject(er);
        });
    });
  }

  /**
   * @description: 发消息
   * const msg = new T_wsMsg();
   * msg.setToUserNo('dev03'); // "__ALLUSERS__"
   * msg.setToClientID(null);
   * msg.setCMD(0); // 0：消息、数据采集类、会谈
   * msg.setMsgType(0); // 0：广播、预警、警报、通知、待办事项、更新token
   * msg.setData('{"userNo":"dev03", "userPass":"123456", "dbName":"test"}');
   * @param {string} userNo 用户编号
   * @param {string} title 消息标题
   * @param {any} liaisonID 联络单ID
   * @return {*}
   * @author: swc
   * @Date: 2024-09-10 11:52:24
   * @LastEditors: zss
   * @LastEditTime: Do not edit
   */
  public sendMessage(userNo: string, title: string, liaisonID: string) {
    const msg = new ts.T_wsMsg();
    const msgBody = new ts.T_msgToDoList();
    msgBody
      .setCategory(0)
      .setLiaisonID(liaisonID)
      .setTitle(title)
      .setContent(`${Tsrv.getI18nBySrv(title)}-审批`);
    msg
      .setToUserNo(userNo)
      .setToClientID(null)
      .setCMD(0)
      .setMsgType(4)
      .setData(msgBody);
    return Tsrv.sendMsg(msg);
  }

  /**
   * @description: 获取内部联络单的row数据
   * @return {*}
   * @author: swc
   * @Date: 2024-11-21 10:57:25
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  public getLiaison(): Promise<any> {
    const that = this.self;
    const dbType = Tsrv.globalVar.dbType.MYSQL;
    const tableName = Tsrv.globalVar.tableName.SYS_INTERNAL_LIAISON_SHEET;
    const gpd = new ts.T_getPartDataArg();
    gpd.setFunName(tableName).setLang(that.$i18n.locale || 'en-US');
    gpd.setPage(1, 99999).setDbType(dbType);
    gpd.setFilter({
      id: {
        $in: [that.liaisonID]
      }
    });
    return Tsrv.getData<any, ifs.I_getPartDataArg>(gpd);
  }

  /**
   * @description: 获取内部联络单明细数据
   * @description: （1、获取所有审批节点数据，2、找到当前审批人）
   * @return {*}
   * @author: swc
   * @Date: 2024-11-21 10:29:33
   * @LastEditors: swc
   * @LastEditTime: Do not edit
   */
  public getLiaisonDet(): Promise<any> {
    const that = this.self;
    const dbType = Tsrv.globalVar.dbType.MYSQL;
    const tableName = Tsrv.globalVar.tableName.SYS_INTERNAL_LIAISON_SHEET_DET;
    const gpd = new ts.T_getPartDataArg();
    gpd.setFunName(tableName).setLang(that.$i18n.locale || 'en-US');
    gpd.setPage(1, 99999).setDbType(dbType);
    gpd.setFilter({
      master_bill_id: { $in: [that.liaisonID] }
    });
    return Tsrv.getData<any, ifs.I_getPartDataArg>(gpd);
  }

  public getTcmd(): T_cmd {
    return this;
  }
}
interface I_cmd extends T_cmd {}
export { I_cmd, T_cmd };
